import phe as paillier
import math
import random

# Generate public and private keys
public_key, private_key = paillier.generate_paillier_keypair()


def multiply_plain_inplace(encrypted_text, plain_text):
    return encrypted_text * plain_text


def sub(et1, et2):
    return et1 - et2


def is_point_in_rectangle(x1, y1, x2, y2, x3, y3, x4, y4, x, y):
    # Encryption parameters

    # compute the difference and then encode them
    p2_p1_x = x2 - x1
    p2_p1_y = y2 - y1
    p4_p3_x = x4 - x3
    p4_p3_y = y4 - y3
    p3_p2_x = x3 - x2
    p3_p2_y = y3 - y2
    p1_p4_x = x1 - x4
    p1_p4_y = y1 - y4

    _x1 = public_key.encrypt(x1)
    _y1 = public_key.encrypt(y1)
    _x2 = public_key.encrypt(x2)
    _y2 = public_key.encrypt(y2)
    _x3 = public_key.encrypt(x3)
    _y3 = public_key.encrypt(y3)
    _x4 = public_key.encrypt(x4)
    _y4 = public_key.encrypt(y4)
    _x = public_key.encrypt(x)
    _y = public_key.encrypt(y)
    print(_x1.ciphertext())
    print(_x2.ciphertext())
    print(_x3.ciphertext())
    print(_x4.ciphertext())
    print(_y1.ciphertext())
    print(_y2.ciphertext())
    print(_y3.ciphertext())
    print(_y4.ciphertext())


    print("The raw and encrypted point x: ")
    print(x, _x)
    print(_x.ciphertext())
    print("The raw and encrypted point y: ")
    print(y, _y)
    print(_y.ciphertext())

    x_x1 = sub(_x, _x1)
    y_y1 = sub(_y, _y1)

    x_x2 = sub(_x, _x2)
    y_y2 = sub(_y, _y2)

    x_x3 = sub(_x, _x3)
    y_y3 = sub(_y, _y3)

    x_x4 = sub(_x, _x4)
    y_y4 = sub(_y, _y4)

    y_y1 = multiply_plain_inplace(y_y1, p2_p1_x)
    x_x1 = multiply_plain_inplace(x_x1, p2_p1_y)
    r1 = sub(y_y1, x_x1)
    res_r1 = private_key.decrypt(r1)
    print(res_r1)

    y_y3 = multiply_plain_inplace(y_y3, p4_p3_x)
    x_x3 = multiply_plain_inplace(x_x3, p4_p3_y)
    r2 = sub(y_y3, x_x3)
    res_r2 = private_key.decrypt(r2)
    print(res_r2)

    y_y2 = multiply_plain_inplace(y_y2, p3_p2_x)
    x_x2 = multiply_plain_inplace(x_x2, p3_p2_y)
    r3 = sub(y_y2, x_x2)
    res_r3 = private_key.decrypt(r3)
    print(res_r3)

    y_y4 = multiply_plain_inplace(y_y4, p1_p4_x)
    x_x4 = multiply_plain_inplace(x_x4, p1_p4_y)
    r4 = sub(y_y4, x_x4)
    res_r4 = private_key.decrypt(r4)
    print(res_r4)

    return res_r1 * res_r2 >= 0 and res_r3 * res_r4 >= 0


if __name__ == '__main__':
    inputs = [4.0, 10.6, 14.7, 10.6, 14.7, 5.3, 4.0, 5.3, 9.3, 7.9]
    print("Plain inputs: ")
    print(inputs)

    if is_point_in_rectangle(*inputs):
        print("The point is inside the rectangle.")
    else:
        print("The point is outside the rectangle.")
